package com.lintf.bot.rabbitmq.delay;

import com.alibaba.fastjson2.JSONObject;
import com.lintf.bot.rabbitmq.AbstractCommonMessageService;
import com.lintf.bot.rabbitmq.constant.Constants;
import com.lintf.bot.rabbitmq.vo.MessageRetryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * @className: TtlTetsConsumer
 * @Description: TODO rabbitmq 补偿机制--发送延时消息
 * @author: wzq
 * @date: 2022/5/13 3:05 PM
 */

@Slf4j
public abstract class CommonMessageDelayService extends AbstractCommonMessageService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送延时消息
     *
     * @param message
     */
    protected void sendDelayMessage(Message message, Exception e) {
        try {
            //封装消息
            MessageRetryVo delayMessageVo = buildMessageRetryInfo(message);
            log.info("延时消息：{}", delayMessageVo);
            //获取所有堆栈信息
            StackTraceElement[] stackTraceElements = e.getStackTrace();
            //默认的异常类全路径为第一条异常堆栈信息的
            String exceptionClassTotalName = stackTraceElements[0].toString();
            //遍历所有堆栈信息，找到第一条异常信息
            for (StackTraceElement stackTraceElement : stackTraceElements) {
                if (stackTraceElement.toString().contains("com.lintf")) {
                    exceptionClassTotalName = stackTraceElement.toString();
                    break;
                }
            }
            log.info("异常信息：{}", exceptionClassTotalName);
            delayMessageVo.setErrorMsg(exceptionClassTotalName);
            delayMessageVo.setType(0);
            prepareAction(delayMessageVo);
        } catch (Exception exception) {
            log.warn("处理消息异常，错误信息：", exception);
        }
    }

    /**
     * 异常消息重新入库
     *
     * @param retryVo
     */
    @Override
    protected void sendMessage(MessageRetryVo retryVo) {
        //将补偿消息实体放入头部，原始消息内容保持不变
        MessageProperties messageProperties = new MessageProperties();
        // 消息的有效时间固定，不使用自定义时间
        messageProperties.setExpiration(String.valueOf(1000 * 10));
        messageProperties.setHeader("message_retry_info", JSONObject.toJSONString(retryVo));
        Message ttlMessage = new Message(JSONObject.toJSONString(retryVo).getBytes(), messageProperties);
        rabbitTemplate.convertAndSend(Constants.DELAY_EXCHANGE, Constants.DELAY_EXCHANGE_ROUTE_KEY, ttlMessage);
        log.info("延时队列发送业务消息 完成 时间：{}", System.currentTimeMillis());
    }

}
